package com.stopboot.code.generator;

import com.stopboot.code.generator.enums.DBTypeEnum;
import com.stopboot.code.generator.modle.ProjectTableInfo;
import com.stopboot.code.generator.modle.TableBo;
import com.stopboot.code.generator.modle.TableColumnBo;
import com.stopboot.code.generator.utils.DbUtils;
import com.stopboot.code.generator.utils.FreemarkerUtil;
import com.stopboot.code.generator.utils.StringUtil;
import freemarker.template.TemplateException;
import org.apache.commons.io.FileUtils;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.*;


/**
 * @version: 0.0.1
 * @author: Lianyutao
 * @create: 2020-05-01 17:32
 * @description: 给自己项目生成标准代码
 **/

public class StopbootMyBatisPlusGeneratorUtil {
    public static final List<String> methodList = Arrays.asList("page", "list","tree", "add", "update", "delete", "detail");
    public static final String SRC_MAIN_JAVA = "/src/main/java/";

    /**
     */

    public static void main(String[] args) throws TemplateException, IOException {

        ProjectTableInfo projectTableInfo = new ProjectTableInfo();
        projectTableInfo.setPath("/Users/lyt/logs");
//        projectTableInfo.setVuePath("/Users/lyt/Dev/cai/stopboot-new/stopboot-vue");
        projectTableInfo.setVuePath("/Users/lyt/Dev/cai/stopboot-template/stopboot-template-admin-vue");
        projectTableInfo.setBasePackage("com.stopboot");
        projectTableInfo.setDbUrl("jdbc:mysql://localhost:3306/");
        projectTableInfo.setDbName("stopboot_admin");
        projectTableInfo.setDbUsername("root");
        projectTableInfo.setDbPassword("12345678");


//        projectTableInfo.setName("用户部门管理");
//        projectTableInfo.setTableName("kw_system_user_dept");
//        projectTableInfo.setModulePath("system/user/dept");

        projectTableInfo.setName("部门管理");
        projectTableInfo.setTableName("kw_system_dept");
        projectTableInfo.setModulePath("system/dept");


        generator(projectTableInfo);
    }

    /**
     * @param projectTableInfo 简介或者模块的意思也可以是表名,数据库表名
     *
     * @throws TemplateException
     * @throws IOException
     */
    public static void generator(ProjectTableInfo projectTableInfo) throws TemplateException, IOException {
        //生成entity,mapper,和service
        String tableName = projectTableInfo.getTableName();
        String modulePath = projectTableInfo.getModulePath();
        Map data = new HashMap();
        data.put("name", projectTableInfo.getName());
        data.put("basePackage", projectTableInfo.getBasePackage());
        data.put("tableName", tableName);
        data.put("modulePath", modulePath);
        //需要支持的方法
        data.put("methodList", methodList);

        String domainName = StringUtil.tableNameToDomain(tableName);
        data.put("domainName", domainName);

        String moduleName = StringUtil.firstWordToUpper(StringUtil.obliquelineToCamel(modulePath));
        data.put("moduleName", moduleName);

        data.put("modulePackage", StringUtil.pathToPackage(modulePath));
        //斜线转驼峰
        data.put("modulePathCamel", StringUtil.obliquelineToCamel(modulePath));

        data.put("version", "1.0.1");
        data.put("author", "LianYuTao");
        data.put("date", new Date());
        data.put("description", tableName);


        //链接指定数据库
        DataSource dataSource = new DriverManagerDataSource(projectTableInfo.getDbUrl() + projectTableInfo.getDbName(), projectTableInfo.getDbUsername(), projectTableInfo.getDbPassword());
        //表信息
        TableBo tableBo = DbUtils.table(dataSource, tableName, DBTypeEnum.MYSQL.getType());
        data.put("tableInfo", tableBo);
        //数据库字段
        List<TableColumnBo> tableColumnVoList = DbUtils.columns(dataSource, tableName, DBTypeEnum.MYSQL.getType());
        data.put("columnList", tableColumnVoList);

        String parentPath = projectTableInfo.getPath() + SRC_MAIN_JAVA;
        String basePackage = projectTableInfo.getBasePackage();

        String basePackagePath = StringUtil.packageToPath(basePackage);


        if (projectTableInfo.isControllerFlag()) {
            {
                //controller
                StringWriter writerService = FreemarkerUtil.process("common/controller.ftl", data);
                System.out.println("writer:\n" + writerService);
                FileUtils.write(new File(parentPath, basePackagePath + "/controller/" + modulePath + "/" + moduleName + "Controller.java"),
                        writerService.getBuffer(),
                        StandardCharsets.UTF_8);
            }

        }

        if (projectTableInfo.isModelFlag()) {
            for (String method : methodList) {

                data.put("currentMethod", method);
                String methodName = StringUtil.firstWordToUpper(method);

                {
                    //生成model的文件路径
                    StringWriter writerService = FreemarkerUtil.process("common/inputParam.ftl", data);
                    System.out.println("writer:\n" + writerService);
                    FileUtils.write(new File(parentPath, basePackagePath + "/model/" + modulePath + "/" + method + "/" + moduleName + methodName + "Params.java"),
                            writerService.getBuffer(),
                            StandardCharsets.UTF_8);
                }


                {
                    //生成model的文件路径
                    StringWriter writerService = FreemarkerUtil.process("common/outputParam.ftl", data);
                    System.out.println("writer:\n" + writerService);
                    FileUtils.write(new File(parentPath, basePackagePath + "/model/" + modulePath + "/" + method + "/" + moduleName + methodName + "Vo.java"),
                            writerService.getBuffer(),
                            StandardCharsets.UTF_8);
                }
            }
        }

        if (projectTableInfo.isServiceFlag()) {
            {
                //Service
                StringWriter writerService = FreemarkerUtil.process("common/service.ftl", data);
                System.out.println("writer:\n" + writerService);
                FileUtils.write(new File(parentPath, basePackagePath + "/service/" + modulePath + "/" + moduleName + "Service.java"),
                        writerService.getBuffer(),
                        StandardCharsets.UTF_8);
            }

            {
                //ServiceImpl
                StringWriter writerService = FreemarkerUtil.process("common/serviceImpl.ftl", data);
                System.out.println("writer:\n" + writerService);
                FileUtils.write(new File(parentPath, basePackagePath + "/service/" + modulePath + "/" + moduleName + "ServiceImpl.java"),
                        writerService.getBuffer(),
                        StandardCharsets.UTF_8);
            }
        }

        if (projectTableInfo.isMapperFlag()) {

            {
                //Mapper
                StringWriter writerService = FreemarkerUtil.process("common/mapper.ftl", data);
                System.out.println("writer:\n" + writerService);
                FileUtils.write(new File(parentPath, basePackagePath + "/mapper/" + domainName + "Mapper.java"),
                        writerService.getBuffer(),
                        StandardCharsets.UTF_8);
            }
        }

        if (projectTableInfo.isEntityFlag()) {
            {
                //entity
                StringWriter writerService = FreemarkerUtil.process("common/entity.ftl", data);
                System.out.println("writer:\n" + writerService);
                FileUtils.write(new File(parentPath, basePackagePath + "/entity/" + domainName + ".java"),
                        writerService.getBuffer(),
                        StandardCharsets.UTF_8);
            }
        }
         if (projectTableInfo.isVueFlag()) {
             String vuePath = projectTableInfo.getVuePath();
             //sdk
             {
                 //src/main/resources/templates/service/common/sdk/js.ftl
                 //src/sdk/modules
                 //entity
                 StringWriter writerService = FreemarkerUtil.process("common/vue/sdk/index.ftl", data);
                 System.out.println("writer:\n" + writerService);
                 FileUtils.write(new File(vuePath + "/src/sdk/modules/" + modulePath + "/index.js"),
                         writerService.getBuffer(),
                         StandardCharsets.UTF_8);
             }
             //页面
             {
                 StringWriter writerService = FreemarkerUtil.process("common/vue/page/index.ftl", data);
                 System.out.println("writer:\n" + writerService);
                 FileUtils.write(new File(vuePath + "/src/views/" + modulePath + "/index.vue"),
                         writerService.getBuffer(),
                         StandardCharsets.UTF_8);
             }
             {
                 StringWriter writerService = FreemarkerUtil.process("common/vue/page/add.ftl", data);
                 System.out.println("writer:\n" + writerService);
                 FileUtils.write(new File(vuePath + "/src/views/" + modulePath + "/add.vue"),
                         writerService.getBuffer(),
                         StandardCharsets.UTF_8);
             }
             {
                 StringWriter writerService = FreemarkerUtil.process("common/vue/page/update.ftl", data);
                 System.out.println("writer:\n" + writerService);
                 FileUtils.write(new File(vuePath + "/src/views/" + modulePath + "/update.vue"),
                         writerService.getBuffer(),
                         StandardCharsets.UTF_8);
             }
         }
    }
}

